<template>
  <div class="files-body">
    <mateFilesGroup
      @change="changeGroup"
      @initChange="initGroup"
      :width="groupWidth + 'px'"
      :isModal="isModal"
    ></mateFilesGroup>
    <div
      v-loading="loading"
      class="files-box"
      :style="{ minWidth: 'calc(100% - 20px - ' + groupWidth + 'px)' }"
    >
      <div class="files-select-group-name">
        <div>{{ activeGroupName }}</div>
        <div class="flex">
          <el-button
            class="mr15"
            v-permission="'mate-files-delete'"
            @click="dels()"
            >删除</el-button
          >
          <div
            v-permission="'mate-files-update-group'"
            v-if="groupList.length > 0"
          >
            <el-dropdown trigger="click" @command="setGroup">
              <el-button class="mr15">移动到分组</el-button>
              <template #dropdown>
                <el-dropdown-menu>
                  <template v-for="(item, index) in groupList" :key="index">
                    <el-dropdown-item :command="item.id">{{
                      item.group_name
                    }}</el-dropdown-item>
                  </template>
                </el-dropdown-menu>
              </template>
            </el-dropdown>
          </div>
          <el-upload
            class="upload-btn"
            :action="apiUrl"
            :headers="headers()"
            :accept="uploadAccept"
            multiple
            :show-file-list="false"
            :on-success="uploadSuccess"
            :on-error="uploadError"
            :on-change="uploadChange"
            :disabled="loading"
          >
            <el-button type="primary" v-permission="'common-upload-image'"
              >上传图片</el-button
            >
          </el-upload>
        </div>
      </div>
      <div
        class="files-list-box"
        ref="filesRef"
        :class="isModal ? 'is-modal' : ''"
      >
        <div class="files-list">
          <template v-for="(item, index) in lists" :key="index">
            <div class="files-item" @click.capture="selectedItem(item)">
              <el-image
                class="img-cover"
                :src="item.file_url"
                :preview-src-list="[item.file_url]"
                hide-on-click-modal
                fit="contain"
                v-if="!isModal"
              /><el-image
                class="img-cover"
                :src="item.file_url"
                fit="contain"
                v-else
              />
              <div class="select-mask" v-if="isModal" v-show="item.active">
                <div class="mask-icon">
                  <i class="icon icon-yes"></i>
                </div>
              </div>
              <div class="file-item-tool">
                <el-checkbox v-model="item.check" v-if="!isModal"></el-checkbox>
                <div class="file-name ml5">{{ item.former_name }}</div>
                <el-dropdown>
                  <span class="icon icon-more-1"></span>
                  <template #dropdown>
                    <el-dropdown-menu>
                      <div v-permission="'mate-files-update-name'">
                        <el-dropdown-item @click="editFileName(item)"
                          >改文件名</el-dropdown-item
                        >
                      </div>
                      <el-dropdown-item @click="copy(item.file_url)"
                        >复制链接</el-dropdown-item
                      >
                      <div v-permission="'mate-files-delete'">
                        <el-dropdown-item @click="del(item.id)"
                          >删除</el-dropdown-item
                        >
                      </div>
                    </el-dropdown-menu>
                  </template>
                </el-dropdown>
              </div>
            </div>
          </template>
          <div v-if="lists.length == 0" class="empty-list">暂无数据</div>
        </div>
        <div class="files-right-box" v-if="isModal">
          <div class="files-right-box-list">
            <template v-for="(item, index) in selectedDataList" :key="index">
              <div
                class="files-item"
                draggable="true"
                @dragstart="dragstart(item)"
                @dragenter="dragenter(item, $event)"
                @dragend="dragend(item, $event)"
                @dragover="dragover($event)"
                @click="delItem(item, index)"
              >
                <image class="img-cover" :src="item" />
                <el-image class="img-cover" :src="item" fit="contain" />
                <div class="yes-icon icon icon-yes1"></div>
              </div>
            </template>
          </div>
          <div class="files-select-count">
            已选择 {{ selectedDataList.length }}/{{ count }}张
          </div>
        </div>
      </div>

      <!-- 分页 -->
      <div class="files-page">
        <el-pagination
          v-model:currentPage="listPage.page"
          :page-size="listPage.limit"
          :background="true"
          layout="total, prev, pager, next"
          :total="listPage.total"
          small="small"
          @current-change="changeCurPage"
          class="mt10"
        />
      </div>
    </div>
    <mateFilesUpdateName
      ref="mateFilesUpdateNameRef"
      @success="toInit()"
    ></mateFilesUpdateName>
  </div>
</template>
<script lang="ts">
export default {
  name: "mateFiles",
};
</script>
    <script lang="ts" setup>
import { onMounted, ref, getCurrentInstance } from "vue";
import mateFilesGroup from "@/components/mate/files-group/index.vue";
import mateFilesUpdateName from "@/components/mate/files/update-name.vue";
import { getList, delFiles, setFilesGroup } from "@/api/mate/files";
import { ElMessageBox } from "element-plus";
import type { UploadFile } from "element-plus";
import router from "@/router/index";
import type { listPageType, Result, ResultError } from "@/types";
import { forEach } from "lodash";

const { proxy } = getCurrentInstance() as any;
const {
  proxy: { $message, $utils },
} = getCurrentInstance() as any;
const props = withDefaults(
  defineProps<{
    isModal?: boolean;
    groupWidth?: string | number;
    count?: number | string;
  }>(),
  {
    isModal: false,
    groupWidth: 386,
    count: 1,
  }
);

const emit = defineEmits(["change"]);

const activeGroupId = ref<number | string>(-1);

const activeGroupName = ref<string>("全部");

const changeGroup = (obj: {
  group_id: number | string;
  group_name: string;
}) => {
  activeGroupId.value = obj.group_id;
  activeGroupName.value = obj.group_name;
  listPage.page = 1;
  toInit();
};

const loading = ref<boolean>(false);

const lists = ref<any>([]);

const selectedIds = ref<any>([]);

const selectedDataList = ref<string | number | string[] | number[] | any>([]);

const listPage: listPageType = {
  total: 0,
  limit: 0,
  page: 1,
};

const changeCurPage = (val: number) => {
  listPage.page = val;
  toInit();
};

const groupList = ref<any>([]);

const initGroup = (data: any) => {
  groupList.value = data;
};

const toInit = () => {
  loading.value = true;
  let obj: any = {};
  obj.page = listPage.page;
  obj.limit = listPage.limit;
  obj.group_id = activeGroupId.value;
  getList(obj)
    .then((res: Result) => {
      lists.value = res.data.data;
      lists.value.forEach((item: any) => {
        item.check = false;
        item.active = false;
      });
      listPage.total = res.data.total;
      initActive();
    })
    .catch((error: ResultError) => {});
  setTimeout(() => {
    loading.value = false;
  }, 1000);
};

const initActive = () => {
  lists.value.forEach((item: any) => {
    if (
      $utils.arrayFilterMultiple(
        selectedDataList.value,
        false,
        item.file_url
      ) !== -1
    ) {
      item.active = true;
    }
  });
};

const uploadAccept = ref<string>(".gif,.jpg,.jpeg,.bmp,.png");

const headers = () => {
  const token = $utils.getStorage("token");
  return {
    Accept: `application/json`,
    "Authori-zation": "Bearer " + token,
  };
};

const apiUrl = ref<string>(import.meta.env.VITE_BASE_URL + "sys/common/upload");

const uploadSuccess = (response: any, uploadFile: typeof UploadFile) => {
  return false;
};

const uploadError = (response: any, uploadFile: typeof UploadFile) => {};

const uploadChange = (res: any) => {
  if (res.response) {
    if (res.response.code == 700) {
      $message.error(res.response.message);
      router.push({
        path: "/login",
        query: {
          redirect: router.currentRoute.value.fullPath,
        },
      });
    } else if (res.response.code != 1) {
      $message.error(res.response.message);
    } else if (res.status == "success") {
      $message.success("文件上传成功");
      toInit();
    }
    loading.value = false;
  } else {
    if (res.status == "ready") {
      loading.value = true;
    }
  }
};

const copy = (fileUrl: string) => {
  $utils.copyDomText(fileUrl);
};

const dels = () => {
  del(getIds());
};

const getIds = () => {
  if (props.isModal) {
    selectedIds.value = [];
    lists.value.forEach((item: { file_url: string; id: number }) => {
      let index = $utils.arrayFilterMultiple(
        selectedDataList.value,
        false,
        item.file_url
      );
      if (index !== -1) {
        selectedIds.value.push(item.id);
      }
    });
    return selectedIds.value.toString();
  } else {
    return $utils
      .getArrayDataByKey(
        $utils.getArrayColumnsByKeyValue(lists.value, "check", true),
        "id"
      )
      .toString();
  }
};

const del = (field: number | string) => {
  if (!field) {
    $utils.errorMsg("请选择图片");
    return false;
  }
  ElMessageBox.confirm("确定删除?", "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "提示:",
  }).then(() => {
    delFiles({
      ids: field,
    })
      .then((res: Result) => {
        toInit();
        $utils.successMsg(res.message);
      })
      .catch((err: ResultError) => {
        $utils.errorMsg(err);
      });
  });
};

const setGroup = (command: string | number) => {
  let ids = getIds();
  if (!ids) {
    $utils.errorMsg("请选择图片");
    return false;
  }
  setFilesGroup({
    ids: ids,
    group_id: command,
  })
    .then((res: Result) => {
      toInit();
      $utils.successMsg(res.message);
    })
    .catch((err: ResultError) => {
      $utils.errorMsg(err);
    });
};

const selectedItem = (item: any) => {
  if (!props.isModal) {
    return;
  }
  let index = $utils.arrayFilterMultiple(
    selectedDataList.value,
    false,
    item.file_url
  );
  if (props.count == 1) {
    selectedDataList.value = item.file_url;
    setYes();
  } else {
    if (index === -1) {
      selectedDataList.value.push(item.file_url);
      item.active = true;
    } else {
      selectedDataList.value.splice(index, 1);
      item.active = false;
    }
  }
};

const delItem = (url: string, index: number) => {
  selectedDataList.value.splice(index, 1);
  let idx = $utils.arrayFilterMultiple(lists.value, "file_url", url);
  if (idx !== -1) {
    lists.value[idx].active = false;
  }
};

const setYes = () => {
  emit("change", selectedDataList.value);
  selectedDataList.value = [];
};

const mateFilesUpdateNameRef = ref<HTMLElement>();

const editFileName = (item: { id: number; former_name: string }) => {
  proxy?.$refs["mateFilesUpdateNameRef"]?.open(item.id, item.former_name);
};

const filesRef = ref<HTMLElement>();

const filesWidth = ref<number>(0);

onMounted(() => {
  if (props.isModal) {
    listPage.limit = 18;
  } else {
    filesWidth.value = proxy?.$refs["filesRef"]?.offsetWidth - 10;
    listPage.limit =
      parseInt(Math.floor(filesWidth.value / 144).toString()) * 3;
  }
});

const open = (selectedData: string | string[] = "") => {
  if (selectedData.length > 0) {
    if (typeof selectedData == "string") {
      selectedData = [selectedData];
    }
    selectedData.forEach((item: string) => {
      selectedDataList.value.push(item);
    });
  }
  toInit();
};

const close = () => {
  lists.value = [];
  listPage.page = 1;
  selectedDataList.value = [];
};

const dragoverOldItem = ref<any>();

const dragoverNewItem = ref<any>();

const dragstart = (value: any) => {
  dragoverOldItem.value = value;
};

// 停止拖拽时触发
const dragend = (value: any, e: any) => {
  // 如果位置没有发生改变 什么也不做
  if (dragoverOldItem.value !== dragoverNewItem.value) {
    let oldIndex = selectedDataList.value.indexOf(dragoverOldItem.value);
    let newIndex = selectedDataList.value.indexOf(dragoverNewItem.value);

    let newItems = [...selectedDataList.value];
    newItems.splice(oldIndex, 1);
    newItems.splice(newIndex, 0, dragoverOldItem.value);
    selectedDataList.value = [...newItems];
    // 如果位置发生了改变
  }
};

// 记录移动过程中信息
const dragenter = (value: any, e: any) => {
  dragoverNewItem.value = value;
  e.preventDefault();
};

// 拖动事件（主要是为了拖动时鼠标光标不变为禁止）
const dragover = (e: any) => {
  e.preventDefault();
};

defineExpose({ open, close, setYes });
</script>
    
    
<style scoped>
::-webkit-scrollbar {
  width: 6px;
}
::-webkit-scrollbar-track {
  background: #fff;
}
::-webkit-scrollbar-thumb {
  background-color: #c6c6c6;
}
.files-body {
  height: 100%;
  display: flex;
  width: 100%;
}
.files-box {
  height: calc(100% - 0px);
  margin-left: 20px;
  box-sizing: border-box;
  border: 1px solid var(--el-border-color-lighter);
  border-radius: 2px;
  font-size: 12px;
}
.files-select-group-name {
  padding: 0 20px;
  background: var(--el-fill-color-lighter);
  text-align: left;
  height: 45px;
  display: flex;
  justify-content: space-between;
  border-bottom: 1px solid var(--el-border-color-lighter);
  align-items: center;
}
.upload-btn {
  display: flex;
  align-items: center;
}
.files-list {
  padding: 10px 0 10px 10px;
  height: 582px;
  width: 100%;
}
.files-list-box.is-modal .files-list {
  width: calc(100% - 90px);
}

.files-list .files-item {
  position: relative;
  cursor: pointer;
  padding: 5px;
  border: 2px solid var(--el-border-color-lighter);
  float: left;
  width: 120px;
  height: 175px;
  margin: 0 10px 10px 0;
}
.files-list .files-item .img-cover {
  width: 100%;
  height: 140px;
}
.file-item-tool {
  display: flex;
  white-space: nowrap;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  margin-top: 5px;
  line-height: 20px;
}
.files-list .files-item div.file-name {
  word-wrap: normal;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
  font-size: 12px;
  width: calc(100% - 40px);
}
.empty-list {
  line-height: 100px;
  text-align: center;
  color: var(--base-grey);
}
.select-mask {
  position: absolute;
  top: -2px;
  bottom: -2px;
  width: 100%;
  height: 100%;
  left: -2px;
  right: -2px;
  background: rgba(0, 0, 0, 0.4);
  text-align: center;
  border: 2px solid var(--base-default);
}
.mask-icon {
  position: absolute;
  left: calc(50% - 20px);
  top: calc(50% - 20px);
  width: 40px;
  height: 40px;
  background: #fff;
  border-radius: 40px;
  text-align: center;
  line-height: 40px;
  color: var(--base-default);
}
.mask-icon .icon {
  font-size: 20px;
}
.files-list-box {
  position: relative;
  display: flex;
  justify-content: space-between;
  height: calc(100% - 96px);
  border-bottom: 1px solid var(--el-border-color-lighter);
}
.files-list-box .files-right-box {
  height: 100%;
  width: 90px;
  border-left: 1px solid var(--el-border-color-lighter);
  text-align: center;
  position: relative;
}
.files-right-box-list {
  overflow: hidden;
  overflow-y: auto;
  position: absolute;
  height: calc(100% - 30px);
  top: 0;
  width: calc(100% - 6px);
  padding-right: 6px;
}
.files-right-box-list .files-item {
  position: relative;
  height: 74px;
  width: 74px;
  margin: 5px;
  border: 1px solid var(--el-border-color-lighter);
  cursor: pointer;
}
.files-right-box-list .files-item:hover {
  border: 1px solid var(--base-default);
}

.files-right-box .files-select-count {
  position: absolute;
  width: 100%;
  bottom: 0;
  line-height: 30px;
  border-top: 1px solid var(--el-border-color-lighter);
}
.files-right-box-list .files-item .img-cover {
  width: 74px;
  height: 74px;
}
.files-right-box-list .files-item .yes-icon {
  position: absolute;
  right: 0;
  top: 0;
  z-index: 1;
  line-height: 20px;
  color: #fff;
}
.files-right-box-list .files-item .yes-icon::after {
  position: absolute;
  content: "";
  right: 0;
  top: 0;
  width: 0;
  height: 0;
  border-top: 30px solid var(--base-default);
  border-left: 40px solid transparent;
  z-index: -1;
}

.files-page {
  display: flex;
  justify-content: end;
  padding: 0 20px;
}
</style>
    